XDL VideoView 활용 네 번째

NXVideoView를 활용하여 동영상 플레이어를 구현해 봅니다.
동영상을 확대/축소, 화면 중심이동, 밝기조절, 회전, Flip, 다양한 필터적용, 화면 캡쳐를 구현해봅니다.

들어가기 전에

본 튜터리얼을 공부하기 전에 먼저 "XDL VideoView 활용 세 번째”를 먼저 선행하시기 바랍니다. XDL VideoView 활용 세 번째에 이어서 진행합니다.

1 메뉴 생성하기
1.1 [도구상자]의 MenuStrip을 선택하고 Form1의 상단부에 드래그하여 위치한다.

1.2 메뉴에 다음과 같이 View, Enhance, Rotate, Flip, Shift, Algor, Capture를 입력하여 생성한다.

1.3 View-ZoomIn, View-ZoomOut기능을 추가한다.

ZoomIn, ZoomOut은 비디오의 뷰 화면을 확대하거나 축소하는 기능을 담당한다.


1.4 Rotate 기능을 추가한다.

Rotate 기능은 화면의 회전을 조절하는 기능을 담당한다.


1.5 Enhance-Contrast, Enhance-Brightness, Enhance-Gamma 기능을 추가한다.

Contrast, Brightness은 각각의 Contrast나 Brightness값을 변경하고, Gamma는 Gamma의 인덱스를 변화시켜서 화면의 밝기를 조절하는 기능을 담당한다.


1.6 Flip-VFlip, Flip-HFlip 기능을 추가한다.

Flip기능은 화면의 좌/우(HFlip)나 상/하(VFlip)를 뒤집어서 도시하는 기능을 한다.


1.7 Shift 기능을 추가한다.

Shift 기능은 화면을 특정 값만큼 이동하는 기능을 담당한다.


1.8 Algorithm 기능을 추가한다.

Algorithm기능은 도시되는 동영상에 다양한 필터기능을 적용하는 기능을 한다. Edge Detection, HDR, Basso, Median, Average필터를 구성한다.


1.9 Capture 기능을 추가한다.

현재 도시되는 Frame과 비디오의 첫번째 Frame을 Capture 캡쳐해서 저장하는 기능을 구현한다.


2 메뉴에 대한 기능 구현
2.1 View에 대한 기능을 구현한다. 비디오에 대한 화면 확대/축소에 대한 기능을 구현한다.

C#

                                
// ZoomIn 메뉴 아이템 클릭시 호출되는 이벤트 함수
private void zoomInToolStripMenuItem_Click(object sender, EventArgs e)
{
    XVertex2d VideoScale = nxVideoView1.Scale;

    if (VideoScale.x > 0)
    {
        if (VideoScale.x >= 2.0) return;
    }
    else
    {
        if (VideoScale.x <= -2.0) return;
    }

    if (VideoScale.y > 0)
    {
        if (VideoScale.y >= 2.0) return;
    }
    else
    {
        if (VideoScale.y <= -2.0) return;
    }

    if (VideoScale.x > 0) VideoScale.x += 0.2; else VideoScale.x -= 0.2;
    if (VideoScale.y > 0) VideoScale.y += 0.2; else VideoScale.y -= 0.2;

    nxVideoView1.Scale = VideoScale;
}

// ZoomOut 메뉴 아이템 클릭시 호출되는 이벤트 함수
private void zoomOutToolStripMenuItem_Click(object sender, EventArgs e)
{
    XVertex2d VideoScale = nxVideoView1.Scale;

    if (VideoScale.x > 0)
    {
        if (VideoScale.x < 0.5) return;
    }
    else
    {
        if (VideoScale.x > -0.5) return;
    }

    if (VideoScale.y > 0)
    {
        if (VideoScale.y < 0.5) return;
    }
    else
    {
        if (VideoScale.y > -0.5) return;
    }

    if (VideoScale.x > 0) VideoScale.x -= 0.2; else VideoScale.x += 0.2;
    if (VideoScale.y > 0) VideoScale.y -= 0.2; else VideoScale.y += 0.2;

    nxVideoView1.Scale = VideoScale;
}
                                
                            

2.2 Enhance에 대한 기능을 구현한다. 비디오에 대한 화면 밝기 조절에 대한 기능을 구현한다.

C#

                                
// 재생되고 있는 동영상의  Contrast 조절
private void contrast02ToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxVideoView1.Contrast += 0.2f;
}

// 재생되고 있는 동영상의  Contrast 조절
private void contrast02ToolStripMenuItem1_Click(object sender, EventArgs e)
{
    nxVideoView1.Contrast -= 0.2f;
}

// 재생되고 있는 동영상의  Brightness 조절
private void brightness02ToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxVideoView1.Brightness += 0.2f;
}

// 재생되고 있는 동영상의  Brightness 조절
private void brightness02ToolStripMenuItem1_Click(object sender, EventArgs e)
{
    nxVideoView1.Brightness -= 0.2f;
}

// 재생되고 있는 동영상의  Gamma 조절
private void gamma04ToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxVideoView1.GammaFactor = 0.4f;
}

// 재생되고 있는 동영상의  Gamma 조절
private void gamma10ToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxVideoView1.GammaFactor = 1.0f;
}
    
// 재생되고 있는 동영상의  Gamma 조절
private void gamma15ToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxVideoView1.GammaFactor = 1.5f;
}

// 재생되고 있는 동영상의  Gamma 조절
private void gamma22ToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxVideoView1.GammaFactor = 2.2f;
}

// 재생되고 있는 동영상의  Gamma 조절
private void gamma40ToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxVideoView1.GammaFactor = 4.0f;
}
                                
                        

2.3 회전에 대한 기능을 구현한다.

C#

                                    
// 재생되고 있는 동영상의 화면을 회전(45도)
private void rotate45ToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxVideoView1.Rotation = new XAngle(45);
}

// 재생되고 있는 동영상의 화면을 회전(-45도)
private void rotate45ToolStripMenuItem1_Click(object sender, EventArgs e)
{
    nxVideoView1.Rotation = new XAngle(-45);
}

// 재생되고 있는 동영상의 화면을 회전(0도)
private void rotate0ToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxVideoView1.Rotation = new XAngle(0);
}
                                    
                            

2.4 Flip에 대한 기능을 구현한다.

C#

                                    
// 동영상 화면을 수직 방향으로 Flip
private void vFlipToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxVideoView1.Scale = new XVertex2d(nxVideoView1.Scale.x, nxVideoView1.Scale.y * -1);
}

// 동영상 화면을 수평 방향으로 Flip
private void hFlipToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxVideoView1.Scale = new XVertex2d(nxVideoView1.Scale.x * -1, nxVideoView1.Scale.y);
}
                                    
                            

2.5 비디오 영상처리에 대한 기능을 구현한다.

C#

                                        
private void edgeDetectionToolStripMenuItem_Click(object sender, EventArgs e)
{
    // Shader를 통해 Edge 필터를 설정
    nxVideoView1.FilterType = eVideoFilterType.Edge;
}

private void hDRToolStripMenuItem_Click(object sender, EventArgs e)
{
    // Shader를 통해 HDR 필터를 설정
    nxVideoView1.EnableHDR = true;
}

private void bassoToolStripMenuItem_Click(object sender, EventArgs e)
{
    // Shader를 통해 Basso 필터를 설정
    nxVideoView1.FilterType = eVideoFilterType.Basso;
}

private void disableToolStripMenuItem_Click(object sender, EventArgs e)
{
    // 필터 설정 해제
    nxVideoView1.FilterType = eVideoFilterType.None;
}

private void medianToolStripMenuItem_Click(object sender, EventArgs e)
{
    // Shader를 통해 Median 필터를 설정
    nxVideoView1.FilterType = eVideoFilterType.Median;
}

private void averageToolStripMenuItem_Click(object sender, EventArgs e)
{
    // Shader를 통해 Average 필터를 설정
    nxVideoView1.FilterType = eVideoFilterType.Average;
}
                                        
                                

2.6 비디오 화면 이동에 대한 기능을 구현한다

C#

                                    
private void shift200200ToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxVideoView1.Translation = new XVertex2d(200, 200);
}

private void shift200200ToolStripMenuItem1_Click(object sender, EventArgs e)
{
    nxVideoView1.Translation = new XVertex2d(-200, -200);
}

private void shift00ToolStripMenuItem_Click(object sender, EventArgs e)
{
    nxVideoView1.Translation = new XVertex2d(0, 0);
}
                                    
                            

2.7 비디오 화면 캡쳐에 대한 기능을 구현한다.

C#

                                    
// 도시되고 있는 현재 프레임을 저장한다. 
private void saveCurrentFrameToolStripMenuItem_Click(object sender, EventArgs e)
{
    if (VS.video == null)
    {
        MessageBox.Show(this, "동영상을 먼저 Open 하세요.", "오류");
        return;
    }

    // 함수 콜 시점의 도시된 영상을 RGB 형식으로 담고 있는 XFramePicture 객체를 생성하여 반환
    XFramePicture frameRGB = VS.videoChannel.GetRenderedFrameRGB();

    SaveFileDialog dlg = new SaveFileDialog();
    dlg.Title = "저장 경로를 설정하세요";
    dlg.OverwritePrompt = true;
    dlg.Filter = "JPEG File(*.jpg)|*.jpg";

    if (dlg.ShowDialog() == DialogResult.OK)
    {
        string strError;
        string strFileName = dlg.FileName;

        // XFramePicture 객체의 화면 프레임을 이미지로 저장
        // 저장을 위한 파일 포맷으로는 TIFF, NITF, JPEG, BMP, JPEG2000 등 지원
        bool bres = frameRGB.SaveFrame(strFileName, "JPEG", out strError, null);

        if (!bres)
        {
            MessageBox.Show(this, "프레임 저장이 실패하였습니다.", "오류");
            return;
        }
    }
}

// 동영상 파일의 첫번째 프레임을 저장한다. 
private void saveFrameFirstFrameToolStripMenuItem_Click(object sender, EventArgs e)
{
    if (VS.video == null)
    {
        MessageBox.Show(this, "동영상을 먼저 Open 하세요.", "오류");
        return;
    }

    SaveFileDialog dlg = new SaveFileDialog();
    dlg.Title = "저장 경로를 설정하세요";
    dlg.OverwritePrompt = true;
    dlg.Filter = "JPEG File(*.jpg)|*.jpg";

    if (dlg.ShowDialog() == DialogResult.OK)
    {
        string strError;
        string strFileName = dlg.FileName;

        // XVidoeIO 객체를 통해 가져온 동영상 스트림의 첫번째 프레임을 반환
        XFramePicture frameRGB = m_videoIO.GetFirstFrameRGB(VS.videoFilePath, "XFFMPDRIVER", out strError);

        // XFramePicture 객체의 화면 프레임을 이미지로 저장
        // 저장을 위한 파일 포맷으로는 TIFF, NITF, JPEG, BMP, JPEG2000 등 지원
        bool bres = frameRGB.SaveFrame(strFileName, "JPEG", out strError, null);

        if (!bres)
        {
            MessageBox.Show(this, "프레임 저장이 실패하였습니다.", "오류");
            return;
        }
    }
}
                                    
                            

2.8 [F5]키를 눌러 프로그램을 실행 후 View, Enhance, Rotate, Flip, Algor, Shift, Capture 툴바를 누르고 하부 기능을 테스트 한다.
1 메뉴 생성하기
1.1 기본으로 생성된 Grid를 두 개의 Row로 나눈 후, 첫 번째 Cell에 Menu를 배치하고 MenuItem 항목을 추가하여 [File]과 [Open]을 생성한다.

자세한 메뉴생성에 대한 설명은 XDL VideoView1 Tutorial을 참고한다.


1.2 이어서 오른쪽 버튼을 눌러 MenuItem추가를 한다. 차례로 [View], [Enhance], [Rotate], [Flip], [Shift], [Algor], [Capture]를 추가로 생성한다.

1.3 [View]-[ZoomIn(+)], [View]-[ZoomOut(-)] 기능을 추가한다. [ZoomIn(+)], [ZoomOut(-)] 은 비디오의 뷰 화면을 “확대”하거나 “축소”하는 기능을 담당한다.

아래 표를 참고하여 메뉴를 생성한다.

Control Type Header Name
MenuItem _View
MenuItem _ZoomIn(+) zoomInViewMenuItem
MenuItem _ZoomOut(-) zoomOutViewMenuItem

1.4 [Enhance]-[Contrast], [Enhance]-[Brightness], [Enhance]-[Gamma] 기능을 추가한다. “Contrast”, “Brightness”은 각각의 “Contrast”나 “Brightness”값을 변경하고, “Gamma”는 “Gamma”의 인덱스를 변화시켜서 화면의 밝기를 조절하는 기능을 담당한다.

아래 표를 참고하여 메뉴를 생성한다.

Control Type Header Name
MenuItem _Enhance
MenuItem _Constant 0.2+ constant02EnhanceMenuItem
MenuItem _Constant 0.2- constant02Enhance2MenuItem
MenuItem _Brightness 0.2+ brightness02EnhanceMenuItem
MenuItem _Brightness 0.2 brightness02Enhance2MenuItem
MenuItem _Gamma 0.4 gamma04EnhanceMenuItem
MenuItem _Gamma 1.0 gamma10EnhanceMenuItem
MenuItem _Gamma 1.5 gamma15EnhanceMenuItem
MenuItem _Gamma 2.2 gamma22EnhanceMenuItem
MenuItem _Gamma 4.0 gamma40EnhanceMenuItem

1.5 [Rotate] 기능을 추가한다. “Rotate”기능은 화면의 회전을 조절하는 기능을 담당한다.

아래 표를 참고하여 메뉴를 생성한다.

Control Type Header Name
MenuItem _Rotate
MenuItem _Rotate +45 rotate45RotateMenuItem
MenuItem _Rotate -45 rotate45Rotate2MenuItem
MenuItem _Rotate 0 rotate0RotateMenuItem

1.6 [Flip]-[VFlip], [Flip]-[HFlip] 기능을 추가한다. “Flip”기능은 화면의 좌/우(HFlip)나 상/하(VFlip) 를 뒤집어서 도시하는 기능을 담당한다.

아래 표를 참고하여 메뉴를 생성한다.

Control Type Header Name
MenuItem _Flip
MenuItem _VFlip vfilpFilpMenuItem
MenuItem _HFlip hfilpFilpMenuItem

1.7 [Shift] 기능을 추가한다. “Shift” 기능은 화면을 특정 값만큼 이동하는 기능을 담당한다.

아래 표를 참고하여 메뉴를 생성한다.

Control Type Header Name
MenuItem _Shift
MenuItem _Shift +200, +200 shift200ShiftMenuItem
MenuItem _Shift -200, -200 shift200Shift2MenuItem
MenuItem _Shift 0, 0 shift0ShiftMenuItem

1.8 [Algorithm] 기능을 추가한다. “Algorithm”기능은 도시되는 동영상에 다양한 필터기능을 적용하는 기능을 담당한다. [Edge Detection], [HDR, Basso], [Median], [Average]필터를 구성한다.

아래 표를 참고하여 메뉴를 생성한다.

Control Type Header Name
MenuItem _Algor
MenuItem _Edge Detection edgedetetionAlgorMenuItem
MenuItem _HDR hdrAlgorMenuItem
MenuItem _Basso bassoAlgorMenuItem
MenuItem _Median medianAlgorMenuItem
MenuItem _Average averageAlgorMenuItem
MenuItem _Disable disableAlgorMenuItem

1.9 [Capture] 기능을 추가한다. 현재 도시되는 Frame과 비디오의 첫번째 Frame을 캡쳐해서 저장하는 기능을 구현한다.

아래 표를 참고하여 메뉴를 생성한다.

Control Type Header Name
MenuItem _Capture
MenuItem _SaveCurrentFrame saveCurrentFrameCaptureMenuItem
MenuItem _SaveFrame_FirstFrame saveFrame_FirstFrameCaptureMenuItem
2 메뉴에 대한 기능 구현
2.1 “View”에 대한 기능을 구현한다. 비디오에 대한 화면 확대/축소에 대한 기능을 구현한다.

C#

                                    
// ZoomIn 메뉴 아이템 클릭 시 호출되는 이벤트 함수
private void zoomInViewMenuItem_Click(object sender, RoutedEventArgs e)
{
    XVertex2d VideoScale = nxVideoView1.Scale;
    if (VideoScale.x > 0)
    {
        if (VideoScale.x >= 2.0) return;
    } else
    {
        if (VideoScale.x <= -2.0) return;
    }
    if (VideoScale.y > 0)
    {
        if (VideoScale.y >= 2.0) return;
    }
    else
    {
        if (VideoScale.y <= -2.0) return;
    }

    if (VideoScale.x > 0) VideoScale.x += 0.2; else VideoScale.x -= 0.2;
    if (VideoScale.y > 0) VideoScale.y += 0.2; else VideoScale.y -= 0.2;
    nxVideoView1.Scale = VideoScale;
}

// ZoomOut 메뉴 아이템 클릭시 호출되는 이벤트 함수
private void zoomOutViewMenuItem_Click(object sender, RoutedEventArgs e)
{
    XVertex2d VideoScale = nxVideoView1.Scale;
    if (VideoScale.x > 0)
    {
        if (VideoScale.x < 0.5) return;
    }
    else
    {
        if (VideoScale.x > -0.5) return;
    }
    if (VideoScale.y > 0)
    {
        if (VideoScale.y < 0.5) return;
    }
    else
    {
        if (VideoScale.y > -0.5) return;
    }

    if (VideoScale.x > 0) VideoScale.x -= 0.2; else VideoScale.x += 0.2;
    if (VideoScale.y > 0) VideoScale.y -= 0.2; else VideoScale.y += 0.2;
    nxVideoView1.Scale = VideoScale;
}
                                    
                            

2.2 “Rotate”에 대한 기능을 구현한다.

C#

                                    
// 재생되고 있는 동영상의 화면을 회전(45도)
private void rotate45RotateMenuItem_Click(object sender, RoutedEventArgs e)
{
    nxVideoView1.Rotation = new XAngle(45);
}

// 재생되고 있는 동영상의 화면을 회전(-45도)
private void rotate45Rotate2MenuItem_Click(object sender, RoutedEventArgs e)
{
    nxVideoView1.Rotation = new XAngle(-45);
}

// 재생되고 있는 동영상의 화면을 회전(0도)
private void rotate0RotateMenuItem_Click(object sender, RoutedEventArgs e)
{
    nxVideoView1.Rotation = new XAngle(0);
}
                                    
                            

2.3 “Enhance”에 대한 기능을 구현한다. 비디오에 대한 화면 밝기 조절에 대한 기능을 구현한다.

C#

                                    
// 재생되고 있는 동영상의 Contrast 조절
private void constrast02EnhanceMenuItem_Click(object sender, RoutedEventArgs e)
{
    nxVideoView1.Contrast += 0.2f;
}

private void constrast02Enhance2MenuItem_Click(object sender, RoutedEventArgs e)
{
    nxVideoView1.Contrast -= 0.2f;
}

// 재생되고 있는 동영상의 Contrast 조절
private void brightness02EnhanceMenuItem_Click(object sender, RoutedEventArgs e)
{
    nxVideoView1.Brightness += 0.2f;
}

private void brightness02Enhance2MenuItem_Click(object sender, RoutedEventArgs e)
{
    nxVideoView1.Brightness -= 0.2f;
}

// 재생되고 있는 동영상의 Gamma 조절
private void gamma04EnhanceMenuItem_Click(object sender, RoutedEventArgs e)
{
    nxVideoView1.GammaFactor = 0.4f;
}

private void gamma10EnhanceMenuItem_Click(object sender, RoutedEventArgs e)
{
    nxVideoView1.GammaFactor = 1.0f;
}

private void gamma15EnhanceMenuItem_Click(object sender, RoutedEventArgs e)
{
    nxVideoView1.GammaFactor = 1.5f;
}

private void gamma22EnhanceMenuItem_Click(object sender, RoutedEventArgs e)
{
    nxVideoView1.GammaFactor = 2.2f;
}

private void gamma40EnhanceMenuItem_Click(object sender, RoutedEventArgs e)
{
    nxVideoView1.GammaFactor = 4.0f;
}
                                    
                            

2.4 “Flip”에 대한 기능을 구현한다.

C#

                                    
// 동영상 화면을 수직 방향으로 Flip
private void vflipFilpMenuItem_Click(object sender, RoutedEventArgs e)
{
    nxVideoView1.Scale = new XVertex2d(nxVideoView1.Scale.x, nxVideoView1.Scale.y * -1);
}

// 동영상 화면을 수평 방향으로 Flip
private void HflipFilpMenuItem_Click(object sender, RoutedEventArgs e)
{
    nxVideoView1.Scale = new XVertex2d(nxVideoView1.Scale.x * -1, nxVideoView1.Scale.y);
}
                                    
                            

2.5 “비디오 화면 영역 이동(Shift)” 대한 기능을 구현한다.

C#

                                    
private void shift200ShiftMenuItem_Click(object sender, RoutedEventArgs e)
{
    nxVideoView1.Translation = new XVertex2d(200, 200);
}

private void shift200Shift2MenuItem_Click(object sender, RoutedEventArgs e)
{
    nxVideoView1.Translation = new XVertex2d(-200, -200);
}

private void shift0ShiftMenuItem_Click(object sender, RoutedEventArgs e)
{
    nxVideoView1.Translation = new XVertex2d(0, 0);
}
                                    
                            

2.6 “비디오 영상처리” 대한 기능을 구현한다.

C#

                                    
private void edgeDetectionAlgorMenuItem_Click(object sender, RoutedEventArgs e)
{
    // Edge 필터 설정
    nxVideoView1.FilterType = eVideoFilterType.Edge;
}

private void hdrAlgorMenuItem_Click(object sender, RoutedEventArgs e)
{
    // HDR 필터 설정
    nxVideoView1.EnableHDR = true;
}

private void bassoAlgorMenuItem_Click(object sender, RoutedEventArgs e)
{
    // Basso 필터 설정
    nxVideoView1.FilterType = eVideoFilterType.Basso;
}

private void medianAlgorMenuItem_Click(object sender, RoutedEventArgs e)
{
    // Median 필터 설정
    nxVideoView1.FilterType = eVideoFilterType.Median;
}

private void averageAlgorMenuItem_Click(object sender, RoutedEventArgs e)
{
    // Average 필터 설정
    nxVideoView1.FilterType = eVideoFilterType.Average;
}

private void diableAlgorMenuItem_Click(object sender, RoutedEventArgs e)
{
    // 필터 설정 해제
    nxVideoView1.FilterType = eVideoFilterType.None;
}
                                    
                            

2.7 “비디오 화면 캡쳐”에 대한 기능을 구현한다.

C#

                                    
// 도시되고 있는 현재 프레임을 저장한다.
private void saveCurrentFrameCaptureMenuItem_Click(object sender, RoutedEventArgs e)
{
    if (VS.video == null)
    {
        MessageBox.Show(this, "동영상을 먼저 Open하세요.", "오류");
        return;
    }

    // 함수 콜 시점의 도시된 영상을 RGB 형식으로 담고 있는 XFramePicture 객체를 생성하여 반환
    XFramePicture frameRGB = VS.videoChannel.GetRenderedFrameRGB();
    SaveFileDialog dlg = new SaveFileDialog();
    dlg.Title = "저장경로설정하십숑";
    dlg.OverwritePrompt = true;
    dlg.Filter = "JPEG File(*.jpg)|*.jpg";

    Nullable<bool> result = dlg.ShowDialog();
    if (result == true)
    {
        string strError;
        string strFileName = dlg.FileName;

        // XFramePicture 객체의 화면 프레임을 이미지로 저장
        // 저장을 위한 파일 포맷으로는 TIFF, NITF, JPEG, BMP, JPEG2000 등 지원
        bool bres = frameRGB.SaveFrame(strFileName, "JPEG", out strError, null);
        if (!bres)
        {
            MessageBox.Show(this, "프레임 저장 실패했습니다", "오류");
            return;
        }
    }
}

private void saveFrame_FirstFrameCaputreMenuItem_Click(object sender, RoutedEventArgs e)
{
    if (VS.video == null)
    {
        MessageBox.Show(this, "동영상을 먼저 Open하세요.", "오류");
        return;
    }

    SaveFileDialog dlg = new SaveFileDialog();
    dlg.Title = "저장경로설정하십숑";
    dlg.OverwritePrompt = true;
    dlg.Filter = "JPEG File(*.jpg)|*.jpg";

    Nullable<bool> result = dlg.ShowDialog();
    if (result == true)
    {
        string strError;
        string strFileName = dlg.FileName;
        // XVideoIO 객체를 통해 가져온 동영상 스트림의 첫번째 프레임을 반환
        XFramePicture frameRGB = m_videoIO.GetFirstFrameRGB(VS.videoFilePath, "XFFMPDRIVER", out strError);
        // XFramePucture 객체의 화면 프레임을 이미지로 저장
        // 저장을 위한 파일 포맷으로는 TIFF, NITF, JPEG, BMP, JPEG200 등 지원
        bool bres = frameRGB.SaveFrame(strFileName, "JPEG", out strError, null);
        if (!bres)
        {
            MessageBox.Show(this, "프레임 저장 실패했습니다", "오류");
            return;
        }
    }
}
                                    
                            

2.8 [F5]키를 눌러 프로그램을 실행 후 [View], [Enhance], [Rotate], [Flip], [Algor], [Shift], [Capture] 누르고 하부 기능을 테스트 한다.